package com.TeamJigsaw.DanteTrail.Presenters;
import java.awt.CardLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

import sun.audio.AudioData;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import sun.audio.ContinuousAudioDataStream;

import com.TeamJigsaw.DanteTrail.Debug.Debug;
import com.TeamJigsaw.DanteTrail.Models.Party;
import com.TeamJigsaw.DanteTrail.Models.PartyMember;
import com.TeamJigsaw.DanteTrail.Models.Player;
import com.TeamJigsaw.DanteTrail.Models.SaveFileHandler;
import com.TeamJigsaw.DanteTrail.Views.MainViewFrame;
import com.TeamJigsaw.DanteTrail.Views.Interfaces.PartySetupInterface;
import com.TeamJigsaw.DanteTrail.Views.Interfaces.ProfessionInterface;
import com.TeamJigsaw.DanteTrail.Views.Interfaces.SplashInterface;

/**
 * This class represents the controller for the initial setup of the party
 * @author Victor
 *
 */
public class IntroviewController implements ViewController{
	private Party party;
	
	private PartySetupInterface setup;
	
	private SplashInterface splash;
	
	private MainViewFrame mainview;
	
	private ProfessionInterface profession;
	
	/**
	 * Creates IntroviewController and initializes its variables
	 * This is the regular constructor used when the user first starts the game
	 * @param mainView The Frame where all the user input is happening
	 */
	public IntroviewController(MainViewFrame mainView) {
		party = new Party();
		this.mainview = mainView;
		setup = this.mainview.getPartySetup();
		splash = this.mainview.getSplash();
		profession = this.mainview.getProfessionScreen();
		createListeners();
		
		try {
			InputStream in = new FileInputStream("resources\\menuBGM.wav");
			AudioStream as = new AudioStream(in);
			AudioData data = as.getData();
			ContinuousAudioDataStream cas = new ContinuousAudioDataStream(data);
			AudioPlayer.player.start(cas);
		} catch (FileNotFoundException e) {
			Debug.println("menuBGM.wav not found!", Debug.WARNING);
		} catch (IOException e) {
			Debug.println("menuBGM.wav could not be loaded!", Debug.WARNING);
		}

	}

	/**
	 * Creates IntroviewController and initializes its variables
	 * This is the possible alternative constructor where the user has already entered 
	 * information in and then goes back to change the names
	 * May not be used
	 * @param mainView The Frame where all the user input is happening
	 */
	public IntroviewController(Party party, MainViewFrame mainView) {
		this.party = party;
		setup = mainView.getPartySetup();
		this.mainview = mainView;
		splash = this.mainview.getSplash();
		profession = this.mainview.getProfessionScreen();
		//NOTE THE TEMPORARY FIX OF SIMPLY REMOVING ALL THE SPACES!
		String member1 = setup.getMember1Name().replaceAll(" ", "");
		String member2 = setup.getMember2Name().replaceAll(" ", "");
		String member3 = setup.getMember3Name().replaceAll(" ", "");
		
		//Change the view of MainView back to Party Setup
		((CardLayout) mainview.getContentPane().getLayout()).show(mainview.getContentPane(), 
				"Party Setup");
		createListeners();

	}

	/**
	 * Sets the initial rations for the party
	 * @param ration The rations to be set 
	 * @return Whether the operation was successful or not
	 */

	public boolean setInitialRation(int ration) {
		if(party != null) {
			party.setRations(ration);
			return true;
		}
		return false;
	}

	/**
	 * Sets the initial pace for the party
	 * @param pace The pace to be set
	 * @return Whether the operation was successful or not
	 */
	public boolean setInitialPace(int pace) {
		if(party != null) {
			party.setPace(pace);
			return true;
		}
		return false;
	}

	/**
	 * Returns an Image based on the file name
	 * @param fileName The file name of the image
	 * @return The image of the file name
	 */
	public Image getImage(String fileName)
	{
		return (new ImageIcon(fileName).getImage());
	}
	
	/**
	 * Creates the listeners for respective buttons in the IntroView
	 */
	@Override
	public void createListeners() {
		//check to see if listeners already exist for the view
		if (setup.listenersExist() == true || profession.listenersExist() == true)
			return;
		
		//sets up a listener to configure UI
		ActionListener listen = new ToPartySetupListener();
		splash.setStartListener(listen);

		//sets up a listener to configure party
		ActionListener partySetupListener = new PartySetupListener();
		setup.setNextListener(partySetupListener);
		
		ActionListener backListen = new BackToSplashListener();
		setup.setBackListener(backListen);

		//sets up a listener to set the profession
		ActionListener professionListener = new ProfessionListener();
		profession.setNextListener(professionListener);
		
		ActionListener backListen1 = new BackToPartySetupListener();
		profession.setBackListener(backListen1);
		
		ActionListener loadListen = new LoadListener();
		splash.setLoadListener(loadListen);

	}
	
	/**
	 * Returns a string representation of the IntroViewController
	 */
	@Override
	public String toString() {
		return ("This is an IntroviewController");
	}
	
	/**
	 * Represents an action listener to take users back to party setup
	 * @author David Chi
	 *
	 */
	private class ToPartySetupListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			((CardLayout) mainview.getContentPane().getLayout()).show(mainview.getContentPane(), "Party Setup");
			mainview.setTitle("Party Setup");

		}
	}
	
	/**
	 * Represents an actionListener to handle party setup
	 * @author David Chi
	 *
	 */
	private class PartySetupListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			String player = setup.getPlayerName();
			String member1 = setup.getMember1Name();
			String member2 = setup.getMember2Name();
			String member3 = setup.getMember3Name();

			if (player.isEmpty() || member1.isEmpty() || 
					member2.isEmpty() || member3.isEmpty()) {
				JOptionPane.showMessageDialog(mainview, "<html>" +
						"<font size=\"4\" color=\"#920F0F\">Please enter " +
						"valid party member names.</font></html>");
			}
			else {
				//empty out existing party members
				party.clear();
				//add the player
				party.addPlayer(new Player(player));
				//party.getPlayer().setProfession(profession.getProfession());
				//add the party members
				party.add(new PartyMember(member1, getImage("resources\\partymember1.gif")));
				party.add(new PartyMember(member2, getImage("resources\\partymember2.gif")));
				party.add(new PartyMember(member3, getImage("resources\\partymembe3.gif")));
				((CardLayout) mainview.getContentPane().getLayout()).show(mainview.getContentPane(), "Profession");
				mainview.setTitle("Profession");
				
			}
		}
	}
	
	/**
	 * Represents an action listener that handles going back to the splash screen
	 * @author David Chi
	 *
	 */
	private class BackToSplashListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			((CardLayout) mainview.getContentPane().getLayout()).show(mainview.getContentPane(), "Splash Screen");	
		}
	}
	
	/**
	 * Represents an action Listener that handles the profession setting
	 * @author David Chi
	 *
	 */
	private class ProfessionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			party.setPace(profession.getPace());
			party.setRations(profession.getRation());
			int money = party.getPlayer().setProfession(profession.getProfession());
			party.setMoney(money);
			
			//TODO: M5 DEMO CODE STARTS
			Debug.println(party.toString(), Debug.M_FIVE_DEMO);
			//TODO: M5 DEMO CODE ENDS
			
			((CardLayout) mainview.getContentPane().getLayout()).show(mainview.getContentPane(), "Shop");
			mainview.setTitle("Shop");
			ShopViewController svc = new ShopViewController(party, mainview);
			svc.setInventoryLabels();
			
		}
	}
	
	/**
	 * Represents an action listener that handles going back to the party setup
	 * @author David Chi
	 *
	 */
	private class BackToPartySetupListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			((CardLayout) mainview.getContentPane().getLayout()).show(mainview.getContentPane(), "Party Setup");
			mainview.setTitle("Party Setup");

		}
	}
	
	private class LoadListener implements ActionListener {
		private IntroviewController intro;
		@Override
		public void actionPerformed(ActionEvent e) {
			SaveFileHandler sfh = new SaveFileHandler();
			try{
				Party loadParty = sfh.read();
				if (loadParty != null)
				{
					party = loadParty;
					((CardLayout) mainview.getContentPane().getLayout()).show(mainview.getContentPane(), "Game");
					mainview.setTitle("Trail");
					GameViewController gvc = new GameViewController(party, mainview);
				}
				else {
					JOptionPane.showMessageDialog(null, "No save file was loaded.");
				}
			}
			catch(IOException ex){
				Debug.println("Loading the file failed. ", Debug.M_TEN_DEMO);
				ex.printStackTrace();
			}

		}
	}
}
